using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Configuration;

namespace GoogleScriptInjector
{
	internal class ScriptInjector : Stream
	{
		private Stream _responseStream;
		private long _position;
		private StringBuilder _responseHtml;

		public ScriptInjector(Stream inputStream)
		{
			_responseStream = inputStream;
			_responseHtml = new StringBuilder();
		}

		#region Filter overrides

		public override bool CanRead
		{
			get { return true; }
		}

		public override bool CanSeek
		{
			get { return true; }
		}

		public override bool CanWrite
		{
			get { return true; }
		}

		public override void Close()
		{
			_responseStream.Close();
		}

		public override void Flush()
		{
			_responseStream.Flush();
		}

		public override long Length
		{
			get { return 0; }
		}

		public override long Position
		{
			get { return _position; }
			set { _position = value; }
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			return _responseStream.Seek(offset, origin);
		}

		public override void SetLength(long length)
		{
			_responseStream.SetLength(length);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return _responseStream.Read(buffer, offset, count);
		}

		#endregion

		#region Script Injector

		public override void Write(byte[] buffer, int offset, int count)
		{
			//get raw html to be flushed to browser
			string html = UTF8Encoding.UTF8.GetString(buffer, offset, count);

			//find the </body> tag so we can inject the google script right before it
			Match match = Regex.Match(html, "</body>");
			if(match.Success) {	html = html.Insert(match.Index, BuildGoogleScript()); }
			
			//get bytes from modified string
			byte[] data = UTF8Encoding.UTF8.GetBytes(html);

			//write and return
			_responseStream.Write(data, 0, data.Length);
		}

		private string BuildGoogleScript()
		{
			StringBuilder script = new StringBuilder();

			script.Append("<script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"text/javascript\"></script>");
			script.Append("<script type=\"text/javascript\">");
			script.Append("_uacct = \"" + ConfigurationManager.AppSettings["GoogleAnalyticsAccountNumber"] + "\";");
			script.Append("urchinTracker();");
			script.Append("</script>");

			return script.ToString();
		}

		#endregion
	}
}
